package com.example.wordbook;
import android.content.Context;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import java.util.List;
//数据仓库，用来做数据的获取，管理数据源
//多线程调用WordDao的方法完成增删改查
//建立仓库类Repository将ViewModel中的数据直接操作的信息提取出来
//创建一个公共类WordRepository
//添加两个成员变量
public class WordRepository {
    private LiveData<List<Word>> allWordsLive;

    private WordDao wordDao;//用来调用数据库操作

   // 添加一个构造函数，该构造函数获取数据库的句柄并初始化成员变量。
    public WordRepository(Context context) {
        WordDatabase wordDatabase = WordDatabase.getDatabase(context.getApplicationContext());
        wordDao = wordDatabase. getWordDao();
        allWordsLive = wordDao.getAllWordsLive();
    }

    //多线程调用WordDao的方法完成增删改查

    //为getAllWords()添加一个包装器，保证单词的正确排列。Room在单独的线程上执行所有查询。观察到LiveData数据更改时，将通知观察者
    public LiveData<List<Word>> getAllWordsLive() {
        return allWordsLive;
    }
    public LiveData<List<Word>> findWordsWithPattern(String patten){
        //通配符保证模糊匹配,通配符%
        return wordDao.findWordsWithPattern("%" + patten + "%");
    }


    //为insert()方法添加一个包装器。使用AsyncTask来执行，确保其是在非UI线程中执行
    //写3个接口来使用这几个类
    void insertWords(Word... words){
        new InsertAsyncTask(wordDao).execute(words);
    }
    void updateWords(Word... words){
        new UpdateAsyncTask(wordDao).execute(words);
    }
    void deleteAllWords(Word... words){
        new DeleteAllAsyncTask(wordDao).execute();
    }

//项目亮点之一：异步操作
    //主要功能是实现多线程
    //异步操作，在子类需要在后台运行的方法；线程运行完成之后要做什么；在处理过程中获取进度，实现类来完成子线程扩展，在UI不能做耗时操作，启动，主线程继续做自己的事情
    //修改页面控件
    //InsertAsyncTask的实现,借助AsyncTask将数据库脱离主线程并放入正确的工作线程中；
    //AsyncTask为抽象类，每个操作都要生成单独的子类
    //AsyncTask就相当于Android给我们提供了一个多线程编程的一个框架，其介于Thread和Handler之间，我们如果要定义一个AsyncTask，就需要定义一个类来继承AsyncTask这个抽象类
    //3个泛型参数：
    //Params: 指定的是我们传递给异步任务执行时的参数的类型
    //Progress: 指定的是我们的异步任务在执行的时候将执行的进度返回给UI线程的参数的类型
    //Result: 指定的是异步任务执行完后返回给UI线程的结果的类型
    //我们在定义一个类继承AsyncTask类的时候，必须指定好这三个泛型的类型，如果都不指定的话，则都将其写成Void，例如：AsyncTask <Void, Void, Void>
    //异步任务的4个步骤：
    //第一步：表示任务执行前的操作（显示进度条）
    //第二步：主要完成耗时操作（在后台执行任务，将进度值传给第三步，将结果传给第四步）
    //第三步：主要是更新UI操作（进度值更新，这个步骤我们看不到）
    //第四步：产生最终结果（产生最终结果）
    static class InsertAsyncTask extends AsyncTask<Word,Void,Void> { //三个参数（泛型）：给后台运行的时候的数据类型，执行过程中的参数，返回参数
        private WordDao wordDao;
        public InsertAsyncTask(WordDao wordDao) {
            this.wordDao = wordDao;
        }
        @Override
        protected Void doInBackground(Word... words) { //三个点：参数为变长类型，都必须在word里面
            wordDao.insertWords(words);
            return null;
        }
    }

    static class UpdateAsyncTask extends AsyncTask<Word,Void,Void>{
        private WordDao wordDao;

        public UpdateAsyncTask(WordDao wordDao) {
            this.wordDao = wordDao;
        }

        @Override
        protected Void doInBackground(Word... words) {
            wordDao.updateWords(words);
            return null;
        }
    }

    static class DeleteAllAsyncTask extends AsyncTask<Void,Void,Void>{
        private WordDao wordDao;

        public DeleteAllAsyncTask(WordDao wordDao) {
            this.wordDao = wordDao;
        }

        @Override
        protected Void doInBackground(Void... voids) {
            wordDao.deleteAllWords();
            return null;
        }
    }
}


